
import 'package:flutter/material.dart';

enum TLBadgeShape { circle, square, spot }

enum TLBadgePosition { topRight, topLeft, bottomRight, bottomLeft }

const double _squareRadius = 1;
const double _spotRadius = 4;
const double _badgeSize = 18;
const double _defaultRadius = -1;

class TLBadge extends StatefulWidget {
  TLBadge(
      {Key key,
        this.color = Colors.red,
        this.shape = TLBadgeShape.circle,
        this.textStyle = const TextStyle(color: Colors.white, fontSize: 8),
        this.position = TLBadgePosition.topRight,
        this.hidden = false,
        this.radius = _defaultRadius,
        this.text,
        @required this.child})
      : assert(child != null),
        super(key: key);

  final Color color;
  final TLBadgeShape shape;
  final TextStyle textStyle;
  final TLBadgePosition position;
  final bool hidden;

  final double radius;
  final String text;
  final Widget child;

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return TLBadgeState();
  }

}

class TLBadgeState extends State<TLBadge> {

  BorderRadius _borderRadius(TLBadgeShape shape) {
    double radius = 0;
    if( widget.radius != _defaultRadius ) {
      radius = widget.radius;
    } else if(widget.shape == TLBadgeShape.circle) {
      radius = _badgeSize / 2;
    } else if(widget.shape == TLBadgeShape.square) {
      radius = _squareRadius;
    } else if(widget.shape == TLBadgeShape.spot) {
      radius = _spotRadius;
    }

    return BorderRadius.circular(radius);
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    TLBadgeShape shape = widget.text != null ? widget.shape : TLBadgeShape.spot;
    double size = shape == TLBadgeShape.spot ? 2 * _spotRadius : _badgeSize;

    Widget textChild = widget.text == null ? null : Center(
      child: Text(
        widget.text,
        style: widget.textStyle,
        textAlign: TextAlign.center,
      ),
    );

    var left, right, top, bottom;
    double offset = size / 3;
    Alignment alignment;
    if(widget.position == TLBadgePosition.topRight) {
      right = -offset;
      top = -offset;
      alignment = Alignment.topRight;
    } else if(widget.position == TLBadgePosition.topLeft) {
      left = -offset;
      top = -offset;
      alignment = Alignment.topLeft;
    } else if(widget.position == TLBadgePosition.bottomRight) {
      right = -offset;
      bottom = -offset;
      alignment = Alignment.bottomRight;
    } else {
      left = -offset;
      bottom = -offset;
      alignment = Alignment.bottomLeft;
    }

    Widget badge = Positioned(
      left: left,
      top: top,
      bottom: bottom,
      right: right,
      width: size,
      height: size,
      child: Container(
        decoration: BoxDecoration(
          color: widget.color,
          borderRadius: _borderRadius(shape)
        ),
        child: textChild,
      ),
    );

    List<Widget> children = widget.hidden ? [widget.child] : [widget.child, badge];

    return Stack(
      alignment: alignment,
      overflow: Overflow.visible,
      children: children,
    );
  }
  
}